﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Xml;
using System.Reflection;
using System.Xml.Serialization;
using Microsoft.CSharp;
using System.CodeDom.Compiler;
using ProtoBuf;

namespace ProtobufTools
{
    public partial class frmMain : Form
    {
        public frmMain()
        {
            InitializeComponent();
        }

        private Assembly assembly = null;

        private ProtobufCompiler compiler = new ProtobufCompiler();

        private void LoadSerializerClassesToTree()
        {
            lstClasses.Items.Clear();

            assembly = Assembly.LoadFrom(txtFile.Text);
            IEnumerable<Type> types = assembly.GetLoadableTypes();

            foreach (Type t in types)
            {
                if (t.CanSerializer())
                {
                    lstClasses.Items.Add(t.FullName);
                }
            }
        }

        private void splitContainer1_Panel1_Paint(object sender, PaintEventArgs e)
        {
        }

        private void btnPack_Click(object sender, EventArgs e)
        {
            Type t = assembly.GetType((string)lstClasses.SelectedItem);
            if (t.IsProtoBufSerializer())
                txtDestation.Text = compiler.Pack(txtSource.Text, t);
            else
                MessageBox.Show(string.Format("class[{0}] isn't a data contract class with protobuf attribute!", (string)lstClasses.SelectedItem));
        }

        private void btnUnpack_Click(object sender, EventArgs e)
        {
            Type t = assembly.GetType((string)lstClasses.SelectedItem);
            if (t.IsProtoBufSerializer())
                txtDestation.Text = compiler.Unpack(txtSource.Text, t);
            else
                MessageBox.Show(string.Format("class[{0}] isn't a data contract class with protobuf attribute!", (string)lstClasses.SelectedItem));
        }

        private void btnSerializer_Click(object sender, EventArgs e)
        {
            if (lstClasses.SelectedIndex != -1)
            {
                Type t = assembly.GetType((string)lstClasses.SelectedItem);
                Object obj = Activator.CreateInstance(t);

                obj.InitSelf();

                XmlSerializer xmlSerializer = new XmlSerializer(t);
                using (MemoryStream memoryStream = new MemoryStream())
                {
                    XmlSerializerNamespaces namespaces = new XmlSerializerNamespaces();
                    namespaces.Add(string.Empty, string.Empty);
                    xmlSerializer.Serialize((Stream)memoryStream, obj, namespaces);
                    txtSource.Text = Encoding.UTF8.GetString(memoryStream.GetBuffer());
                }
            }
        }

        private void btnBrowser_Click(object sender, EventArgs e)
        {
            OpenFileDialog dialog = new OpenFileDialog();
            dialog.Title = "选择文件";
            dialog.Filter = "Dll File(*.dll)|*.dll|Execute File(*.exe)|*.exe|All Support File(*.exe;*.dll)|*.exe;*.dll";            

            if (dialog.ShowDialog() == DialogResult.OK)
            {
                txtFile.Text = dialog.FileName;
                LoadSerializerClassesToTree();
            }
        }

        private void txtSource_TextChanged(object sender, EventArgs e)
        {
            txtSource.Text = txtSource.Text.Replace("><", ">\n<");
        }
    }
}
